home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / comm / tr4_23.zip / TRFIFO.C < prev    next >
C/C++ Source or Header  |  1991-12-02  |  9KB  |  312 lines

  1. /*
  2.  * Filename: TRFIFO.C
  3.  * Author:   Douglas Thomson, MUCG, Churchill, Victoria, AUSTRALIA
  4.  * Status:   Public Domain
  5.  * History:  02-Dec-91  prepared source code for release
  6.  */
  7.  
  8. /*
  9.  * trfifo: link two users via UNIX FIFO files
  10.  *
  11.  * Instructions:
  12.  *      1. run trfifo on the HOST PC:
  13.  *              trfifo host
  14.  *      2. enter any name, say "test" at the prompt
  15.  *      3. exit to DOS, but KEEP connection
  16.  *      4. run TRHOST
  17.  *      5. run trfifo on the REPLICA PC:
  18.  *              trfifo
  19.  *      6. enter the SAME name ("test") at the prompt
  20.  *      7. exit to DOS, but KEEP connection (if not using TR to log in)
  21.  *      8. run TR (if not using TR to log in)
  22.  *      9. when finished, exit TR with F10/3 (host PC will reboot)
  23.  *     10. normally host will keep running trfifo ready for next login. To
  24.  *         stop trfifo on host, send DEL from host PC.
  25.  */
  26. #include <stdio.h>
  27. #include <fcntl.h>
  28. #include <signal.h>
  29. #include <sys/types.h>
  30. #include <sys/stat.h>
  31. #include <termio.h>
  32. #include <sys/ioctl.h>
  33.  
  34. #define TRUE 1
  35. #define FALSE 0
  36. #define OK 0
  37. #define ERROR (-1)
  38. #define FIFO ( S_IFIFO | 0666 )
  39. #define IN 0
  40. #define OUT 1
  41.  
  42. #define BUFF_SIZE 128
  43.  
  44. struct termio oldtty, tty;      /* used for setting RAW I/O */
  45. int iofd = 0;                   /* file descriptor for setting RAW I/O */
  46. char readfile[BUFF_SIZE];       /* name of host input FIFO */
  47. char writefile[BUFF_SIZE];      /* name of host output FIFO */
  48.  
  49. /*
  50.  * restore tty to its original state
  51.  */
  52. void terminate(status)
  53. int status;
  54. {
  55.     /*
  56.      * go back to normal I/O - borrowed from rbsb.c from the zmodem
  57.      *  package.
  58.      */
  59.     (void) ioctl(iofd, TCSBRK, 1);          /* wait for output to drain */
  60.     (void) ioctl(iofd, TCFLSH, 1);          /* flush input queue */
  61.     (void) ioctl(iofd, TCSETAW, &oldtty);   /* restore original modes */
  62.     (void) ioctl(iofd, TCXONC,1);           /* restart output */
  63.  
  64.     /*
  65.      * don't leave inactive pipes around
  66.      */
  67.     unlink(readfile);
  68.     unlink(writefile);
  69.  
  70.     exit(status);
  71. }
  72.  
  73. /*
  74.  * trap interrupts so that tty state can be restored
  75.  */
  76. void int_handler()
  77. {
  78.     terminate(0);
  79. }
  80.  
  81. void main(argc, argv)
  82. int argc;
  83. char *argv[];
  84. {
  85.     char sys_name[256];             /* base name of FIFO link */
  86.     unsigned char buff[BUFF_SIZE];  /* buffer for transferred characters */
  87.     int n;                          /* number of characters read */
  88.     unsigned char c;                /* a general purpose character! */
  89.     int readfd;                     /* file descriptor for reading FIFO */
  90.     int writefd;                    /* file descriptor for writing FIFO */
  91.     int child;                      /* PID for child process */
  92.     int host;                       /* is this the host end? */
  93.     static struct sigaction act;    /* used for catching BREAK */
  94.     int first = TRUE;               /* first time around? */
  95.  
  96.     /*
  97.      * store settings for later
  98.      */
  99.     (void) ioctl(iofd, TCGETA, &oldtty);
  100.  
  101. restart:  /* come back here after each session */
  102.  
  103.     /*
  104.      * ignore BREAK for a bit
  105.      */
  106.     tty = oldtty;                   /* save original settings for later */
  107.     tty.c_iflag &= ~BRKINT;         /* DO NOT allow BREAK to kill */
  108.     tty.c_iflag |= IGNBRK;          /* ignore BREAK */
  109.     (void) ioctl(iofd, TCSETAW, &tty);
  110.  
  111.  
  112.     if (first) {
  113.         if (argc > 3 || (argc == 3 && strcmp(argv[1], "host") != 0)) {
  114.             fprintf(stderr, "Usage: trfifo [host] [<FIFO name>]\n");
  115.             terminate(1);
  116.         }
  117.  
  118.         if (argc > 1 && strcmp(argv[1], "host") == 0) {
  119.             host = TRUE;
  120.         }
  121.         else {
  122.             host = FALSE;
  123.         }
  124.  
  125.         if (argc != 3) { /* no output for command line version of host */
  126.             printf("TRFifo PC linking utility\n");
  127.         }
  128.  
  129.         if (argc == host + 1) {
  130.             printf("Enter system name (e.g. as1): ");
  131.             fflush(stdout);
  132.             gets(sys_name);
  133.         }
  134.         else {
  135.             strcpy(sys_name, argv[host+1]);
  136.         }
  137.  
  138.         if (argc != 3) { /* no output for command line version of host */
  139.             printf("Setting up %s '%s'\n", host ? "host" : "replica", sys_name);
  140.         }
  141.  
  142.         /*
  143.          * Name the FIFOs - the host gets sensible names, the replica gets
  144.          *  reversed names!
  145.          */
  146.         if (host) {
  147.             sprintf(readfile, "/tmp/in_%s", sys_name);
  148.             sprintf(writefile, "/tmp/out_%s", sys_name);
  149.         }
  150.         else {
  151.             sprintf(readfile, "/tmp/out_%s", sys_name);
  152.             sprintf(writefile, "/tmp/in_%s", sys_name);
  153.         }
  154.     }
  155.  
  156.     /*
  157.      * Create the FIFOs
  158.      */
  159.     if (host) {
  160.         umask(0);                   /* let anyone into the FIFO */
  161.         unlink(readfile);           /* kill old FIFO from last crash? */
  162.         if (mknod(readfile, FIFO) == ERROR) {
  163.             perror(readfile);
  164.             terminate(1);
  165.         }
  166.         unlink(writefile);
  167.         if (mknod(writefile, FIFO) == ERROR) {
  168.             perror(writefile);
  169.             unlink(readfile);
  170.             terminate(1);
  171.         }
  172.     }
  173.  
  174.     if (host && first) {
  175.         printf("Return to DOS (keeping connection) and run TRHOST\n");
  176.         fflush(stdout);
  177.     }
  178.  
  179.     /*
  180.      * catch interrupt
  181.      */
  182.     act.sa_handler = int_handler;
  183.     sigaction(SIGINT, &act, NULL);
  184.  
  185.     /*
  186.      * pipes are opened in the opposite order, so that deadlock does
  187.      *  not occur waiting to open pipes...
  188.      */
  189.     if (host) {
  190.         if ((readfd = open(readfile, O_RDONLY)) == ERROR) {
  191.             perror("can't open FIFO for reading");
  192.             unlink(readfile);
  193.             unlink(writefile);
  194.             terminate(1);
  195.         }
  196.         if ((writefd = open(writefile, O_WRONLY)) == ERROR) {
  197.             perror("can't open FIFO for writing");
  198.             unlink(readfile);
  199.             unlink(writefile);
  200.             terminate(1);
  201.         }
  202.     }
  203.     else {
  204.         if ((writefd = open(writefile, O_WRONLY)) == ERROR) {
  205.             /*
  206.              * This probably means the host is not running or is in use
  207.              *  by someone else...
  208.              */
  209.             fprintf(stderr, "Sorry, '%s' is not currently available\n",
  210.                     sys_name);
  211.             terminate(1);
  212.         }
  213.         if ((readfd = open(readfile, O_RDONLY)) == ERROR) {
  214.             perror("can't open FIFO for reading");
  215.             terminate(1);
  216.         }
  217.     }
  218.  
  219.     /*
  220.      * have established the FIFO, remove the files so no-one else can
  221.      *  interfere...
  222.      */
  223.     unlink(readfile);
  224.     unlink(writefile);
  225.  
  226.     if (!host) {
  227.         printf("Return to DOS (keeping connection) and run TR\n");
  228.         fflush(stdout);
  229.     }
  230.  
  231.     first = FALSE;
  232.  
  233.     /*
  234.      * go into transparent 8-bit raw I/O etc etc - largely inspired by the
  235.      *  rbsb.c file in the zmodem package. See this file for ideas if you
  236.      *  have an incompatible flavor of UNIX...
  237.      */
  238.     tty = oldtty;                   /* save original settings for later */
  239.     tty.c_iflag = BRKINT;           /* DO allow BREAK to kill */
  240.     tty.c_lflag &= ~(ECHO | ICANON | ISIG); /* no echo etc etc*/
  241.     tty.c_oflag = 0;                /* no output processing */
  242.     tty.c_cflag &= ~PARENB;         /* disable parity */
  243.     tty.c_cflag |= CS8;             /* set character size to 8 bits */
  244.     tty.c_cc[VMIN] = BUFF_SIZE;     /* try to read a decent block */
  245.     tty.c_cc[VTIME] = 1;            /* give up after 0.1 seconds */
  246.     (void) ioctl(iofd, TCSETAW, &tty);
  247.  
  248.     /*
  249.      * One process reads the input FIFO and copies it to STDOUT; the other
  250.      *  reads STDIN and copies it to the output FIFO.
  251.      */
  252.     switch (child = fork()) {
  253.     case ERROR:
  254.         perror("fork");
  255.         terminate(1);
  256.     case 0:
  257.         for (;;) {
  258.             n = read(0, buff, BUFF_SIZE);
  259.             if (n > 0) {
  260.                 write(writefd, buff, n);
  261.             }
  262.         }
  263.     default:
  264.         for (;;) {
  265.             if ((n = read(readfd, buff, BUFF_SIZE)) <= 0) {
  266.                 break;
  267.             }
  268.             write(1, buff, n);
  269.         }
  270.         if (host) {
  271.             /*
  272.              * the replica has just terminated, so send a reboot command
  273.              *  to the host
  274.              */
  275.  
  276.             /*
  277.              * ensure BREAK is ignored before rebooting PC
  278.              */
  279.             tty = oldtty;                   /* save original settings for later */
  280.             tty.c_iflag &= ~BRKINT;         /* DO NOT allow BREAK to kill */
  281.             tty.c_iflag |= IGNBRK;          /* ignore BREAK */
  282.             (void) ioctl(iofd, TCSETAW, &tty);
  283.  
  284.             c = 0;
  285.             write(1, &c, 1);
  286.             write(1, &c, 1);
  287.             c = 3;
  288.             write(1, &c, 1);
  289.             sleep(1);
  290.             c = 0;
  291.             write(1, &c, 1);
  292.             write(1, &c, 1);
  293.             c = 3;
  294.             write(1, &c, 1);
  295.  
  296.             kill(child, SIGINT);           /* don't leave orphan */
  297.             wait(NULL);
  298.  
  299.             goto restart;
  300.         }
  301.  
  302.         /*
  303.          * don't leave orphan processes...
  304.          */
  305.         kill(child, SIGINT);
  306.         wait(NULL);
  307.     }
  308.  
  309.     terminate(0);
  310. }
  311.  
  312.